package cn.metona.mq.core;

import java.io.Serial;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;

/**
 * 消息实体类
 * 包含消息的所有元数据和业务数据
 */
public record Message(
        String messageId,           // 消息唯一ID
        String topic,              // 消息主题
        String body,               // 消息体
        int priority,              // 消息优先级
        LocalDateTime createTime,  // 创建时间
        LocalDateTime expireTime,  // 过期时间
        Map<String, String> headers, // 消息头
        String tag,                // 消息标签
        long delayTime             // 延迟时间(毫秒)
) implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 构造函数 - 自动生成消息ID和创建时间
     */
    public Message(String topic, String body) {
        this(UUID.randomUUID().toString(), topic, body, 0,
                LocalDateTime.now(), null, new ConcurrentHashMap<>(), null, 0L);
    }

    /**
     * 构造函数 - 支持自定义优先级
     */
    public Message(String topic, String body, int priority) {
        this(UUID.randomUUID().toString(), topic, body, priority,
                LocalDateTime.now(), null, new ConcurrentHashMap<>(), null, 0L);
    }

    /**
     * 构造函数 - 支持延迟消息
     */
    public Message(String topic, String body, long delayTime) {
        this(UUID.randomUUID().toString(), topic, body, 0,
                LocalDateTime.now(), null, new ConcurrentHashMap<>(), null, delayTime);
    }

    /**
     * 构造函数 - 完整参数
     */
    public Message {
        if (topic == null || topic.isEmpty()) {
            throw new IllegalArgumentException("Topic cannot be null or empty");
        }
        if (body == null) {
            throw new IllegalArgumentException("Body cannot be null");
        }
        if (messageId == null) {
            messageId = UUID.randomUUID().toString();
        }
        if (createTime == null) {
            createTime = LocalDateTime.now();
        }
        if (headers == null) {
            headers = new ConcurrentHashMap<>();
        }
    }

    /**
     * 设置消息头
     */
    public void setHeader(String key, String value) {
        if (key != null && value != null) {
            this.headers.put(key, value);
        }
    }

    /**
     * 获取消息头
     */
    public String getHeader(String key) {
        return key != null ? this.headers.get(key) : null;
    }

    /**
     * 判断消息是否过期
     */
    public boolean isExpired() {
        return expireTime != null && LocalDateTime.now().isAfter(expireTime);
    }

    /**
     * 判断消息是否延迟
     */
    public boolean isDelayed() {
        return delayTime > 0 && LocalDateTime.now().isBefore(getDelayExpireTime());
    }

    /**
     * 获取延迟到期时间
     */
    public LocalDateTime getDelayExpireTime() {
        return delayTime > 0 ? createTime.plusNanos(delayTime * 1_000_000) : createTime;
    }
}